#!/usr/bin/env python3
# 
# Cross Platform and Multi Architecture Advanced Binary Emulation Framework
#

from collections import namedtuple
opcode_map = namedtuple('opcode', ['mnemonic', 'description'])

opcodes = {
    0x00: opcode_map('STOP', 'Halts execution.'),
    0x01: opcode_map('ADD', 'Addition operation.'),
    0x02: opcode_map('MUL', 'Multiplication operation.'),
    0x03: opcode_map('SUB', 'Subtraction operation.'),
    0x04: opcode_map('DIV', 'Integer division operation.'),
    0x05: opcode_map('SDIV', 'Signed integer division operation (truncated).'),
    0x06: opcode_map('MOD', 'Modulo remainder operation.'),
    0x07: opcode_map('SMOD', 'Signed modulo remainder operation.'),
    0x08: opcode_map('ADDMOD', 'Modulo addition operation.'),
    0x09: opcode_map('MULMOD', 'Modulo multiplication operation.'),
    0x0a: opcode_map('EXP', 'Exponential operation.'),
    0x0b: opcode_map('SIGNEXTEND', "Extend length of two's complement signed integer."),
    
    0x10: opcode_map('LT', 'Less-than comparision.'),
    0x11: opcode_map('GT', 'Greater-than comparision.'),
    0x12: opcode_map('SLT', 'Signed less-than comparision.'),
    0x13: opcode_map('SGT', 'Signed greater-than comparision.'),
    0x14: opcode_map('EQ', 'Equality comparision.'),
    0x15: opcode_map('ISZERO', 'Simple not operator.'),
    0x16: opcode_map('AND', 'Bitwise AND operation.'),
    0x17: opcode_map('OR', 'Bitwise OR operation.'),
    0x18: opcode_map('XOR', 'Bitwise XOR operation.'),
    0x19: opcode_map('NOT', 'Bitwise NOT operation.'),
    0x1a: opcode_map('BYTE', 'Retrieve single byte from word.'),
    0x1b: opcode_map('SHL', 'Bitwise left shift'),
    0x1c: opcode_map('SHR', 'Bitwise right shift'),
    0x1d: opcode_map('SAR', 'Arithmetic bitwise right shift'),

    0x20: opcode_map('SHA3', 'Compute Keccak-256 hash.'),  # SHA3
    
    0x30: opcode_map('ADDRESS', 'Get address of currently executing account.'),
    0x31: opcode_map('BALANCE', 'Get balance of the given account.'),
    0x32: opcode_map('ORIGIN', 'Get execution origination address.'),
    0x33: opcode_map('CALLER', 'Get caller address.'),
    0x34: opcode_map('CALLVALUE', 'Get deposited value by the instruction/transaction responsible for this execution.'),
    0x35: opcode_map('CALLDATALOAD', 'Get input data of current environment.'),
    0x36: opcode_map('CALLDATASIZE', 'Get size of input data in current environment.'),
    0x37: opcode_map('CALLDATACOPY', 'Copy input data in current environment to memory.'),
    0x38: opcode_map('CODESIZE', 'Get size of code running in current environment.'),
    0x39: opcode_map('CODECOPY', 'Copy code running in current environment to memory.'),
    0x3a: opcode_map('GASPRICE', 'Get price of gas in current environment.'),
    0x3b: opcode_map('EXTCODESIZE', "Get size of an account's code."),
    0x3c: opcode_map('EXTCODECOPY', "Copy an account's code to memory."),
    0x3d: opcode_map('RETURNDATASIZE', "get size of return data buffer"),
    0x3e: opcode_map('RETURNDATACOPY', "copy return data in current environment to memory"),
    
    0x40: opcode_map('BLOCKHASH', 'Get the hash of one of the 256 most recent complete blocks.'),
    0x41: opcode_map('COINBASE', "Get the block's beneficiary address."),
    0x42: opcode_map('TIMESTAMP', "Get the block's timestamp."),
    0x43: opcode_map('NUMBER', "Get the block's number."),
    0x44: opcode_map('DIFFICULTY', "Get the block's difficulty."),
    0x45: opcode_map('GASLIMIT', "Get the block's gas limit."),
    
    0x50: opcode_map('POP', 'Remove item from stack.'),
    0x51: opcode_map('MLOAD', 'Load word from memory.'),
    0x52: opcode_map('MSTORE',  'Save word to memory.'),
    0x53: opcode_map('MSTORE8', 'Save byte to memory.'),
    0x54: opcode_map('SLOAD', 'Load word from storage.'),
    0x55: opcode_map('SSTORE', 'Save word to storage.'),
    0x56: opcode_map('JUMP', 'Alter the program counter.'),
    0x57: opcode_map('JUMPI', 'Conditionally alter the program counter.'),
    0x58: opcode_map('PC', 'Get the value of the program counter prior to the increment.'),
    0x59: opcode_map('MSIZE', 'Get the size of active memory in bytes.'),
    0x5a: opcode_map('GAS', 'Get the amount of available gas, including the corresponding reduction the amount of available gas.'),
    0x5b: opcode_map('JUMPDEST', 'Mark a valid destination for jumps.'),
    
    0x60: opcode_map('PUSH1', 'Place 1 byte item on stack.'),
    0x61: opcode_map('PUSH2', 'Place 2-byte item on stack.'),
    0x62: opcode_map('PUSH3', 'Place 3-byte item on stack.'),
    0x63: opcode_map('PUSH4', 'Place 4-byte item on stack.'),
    0x64: opcode_map('PUSH5', 'Place 5-byte item on stack.'),
    0x65: opcode_map('PUSH6', 'Place 6-byte item on stack.'),
    0x66: opcode_map('PUSH7', 'Place 7-byte item on stack.'),
    0x67: opcode_map('PUSH8', 'Place 8-byte item on stack.'),
    0x68: opcode_map('PUSH9', 'Place 9-byte item on stack.'),
    0x69: opcode_map('PUSH10', 'Place 10-byte item on stack.'),
    0x6a: opcode_map('PUSH11', 'Place 11-byte item on stack.'),
    0x6b: opcode_map('PUSH12', 'Place 12-byte item on stack.'),
    0x6c: opcode_map('PUSH13', 'Place 13-byte item on stack.'),
    0x6d: opcode_map('PUSH14', 'Place 14-byte item on stack.'),
    0x6e: opcode_map('PUSH15', 'Place 15-byte item on stack.'),
    0x6f: opcode_map('PUSH16', 'Place 16-byte item on stack.'),
    0x70: opcode_map('PUSH17', 'Place 17-byte item on stack.'),
    0x71: opcode_map('PUSH18', 'Place 18-byte item on stack.'),
    0x72: opcode_map('PUSH19', 'Place 19-byte item on stack.'),
    0x73: opcode_map('PUSH20', 'Place 20-byte item on stack.'),
    0x74: opcode_map('PUSH21', 'Place 21-byte item on stack.'),
    0x75: opcode_map('PUSH22', 'Place 22-byte item on stack.'),
    0x76: opcode_map('PUSH23', 'Place 23-byte item on stack.'),
    0x77: opcode_map('PUSH24', 'Place 24-byte item on stack.'),
    0x78: opcode_map('PUSH25', 'Place 25-byte item on stack.'),
    0x79: opcode_map('PUSH26', 'Place 26-byte item on stack.'),
    0x7a: opcode_map('PUSH27', 'Place 27-byte item on stack.'),
    0x7b: opcode_map('PUSH28', 'Place 28-byte item on stack.'),
    0x7c: opcode_map('PUSH29', 'Place 29-byte item on stack.'),
    0x7d: opcode_map('PUSH30', 'Place 30-byte item on stack.'),
    0x7e: opcode_map('PUSH31', 'Place 31-byte item on stack.'),
    0x7f: opcode_map('PUSH32', 'Place 32-byte (full word) item on stack.'),
    0x80: opcode_map('DUP1', 'Duplicate 1st stack item.'),
    0x81: opcode_map('DUP2', 'Duplicate 2nd stack item.'),
    0x82: opcode_map('DUP3', 'Duplicate 3rd stack item.'),
    0x83: opcode_map('DUP4', 'Duplicate 4th stack item.'),
    0x84: opcode_map('DUP5', 'Duplicate 5th stack item.'),
    0x85: opcode_map('DUP6', 'Duplicate 6th stack item.'),
    0x86: opcode_map('DUP7', 'Duplicate 7th stack item.'),
    0x87: opcode_map('DUP8', 'Duplicate 8th stack item.'),
    0x88: opcode_map('DUP9', 'Duplicate 9th stack item.'),
    0x89: opcode_map('DUP10', 'Duplicate 10th stack item.'),
    0x8a: opcode_map('DUP11', 'Duplicate 11th stack item.'),
    0x8b: opcode_map('DUP12', 'Duplicate 12th stack item.'),
    0x8c: opcode_map('DUP13', 'Duplicate 13th stack item.'),
    0x8d: opcode_map('DUP14', 'Duplicate 14th stack item.'),
    0x8e: opcode_map('DUP15', 'Duplicate 15th stack item.'),
    0x8f: opcode_map('DUP16', 'Duplicate 16th stack item.'),
    0x90: opcode_map('SWAP1', 'Exchange 1st and 2nd stack items.'),
    0x91: opcode_map('SWAP2', 'Exchange 1st and 3rd stack items.'),
    0x92: opcode_map('SWAP3', 'Exchange 1st and 4th stack items.'),
    0x93: opcode_map('SWAP4', 'Exchange 1st and 5th stack items.'),
    0x94: opcode_map('SWAP5', 'Exchange 1st and 6th stack items.'),
    0x95: opcode_map('SWAP6', 'Exchange 1st and 7th stack items.'),
    0x96: opcode_map('SWAP7', 'Exchange 1st and 8th stack items.'),
    0x97: opcode_map('SWAP8', 'Exchange 1st and 9th stack items.'),
    0x98: opcode_map('SWAP9', 'Exchange 1st and 10th stack items.'),
    0x99: opcode_map('SWAP10', 'Exchange 1st and 11th stack items.'),
    0x9a: opcode_map('SWAP11', 'Exchange 1st and 12th stack items.'),
    0x9b: opcode_map('SWAP12', 'Exchange 1st and 13th stack items.'),
    0x9c: opcode_map('SWAP13', 'Exchange 1st and 14th stack items.'),
    0x9d: opcode_map('SWAP14', 'Exchange 1st and 15th stack items.'),
    0x9e: opcode_map('SWAP15', 'Exchange 1st and 16th stack items.'),
    0x9f: opcode_map('SWAP16', 'Exchange 1st and 17th stack items.'),
    0xa0: opcode_map('LOG0', 'Append log record with no topics.'),
    0xa1: opcode_map('LOG1', 'Append log record with one topic.'),
    0xa2: opcode_map('LOG2', 'Append log record with two topics.'),
    0xa3: opcode_map('LOG3', 'Append log record with three topics.'),
    0xa4: opcode_map('LOG4', 'Append log record with four topics.'),
    0xf0: opcode_map('CREATE', 'Create a new account with associated code.'),
    0xf1: opcode_map('CALL', 'Message-call into an account.'),
    0xf2: opcode_map('CALLCODE', "Message-call into this account with alternative account's code."),
    0xf3: opcode_map('RETURN', 'Halt execution returning output data.'),
    0xf4: opcode_map('DELEGATECALL', "like CALLCODE but keeps caller's value and sender"),
    0xfa: opcode_map('STATICCALL', 'like CALL but disallow state modifications'),
    0xfb: opcode_map('CREATE2', 'create new account with associated code at address `sha3(sender + salt + sha3(init code)) % 2**160`'),
    0xfd: opcode_map('REVERT', 'halt execution, revert state and return output data'),
    0xfe: opcode_map('INVALID', 'old ASSERTFAIL - invalid instruction for expressing runtime errors (e.g., division-by-zero)'),
    0xff: opcode_map('SELFDESTRUCT', 'Halt execution and register account for later deletion.')
}